package com._54programer.demo.hello;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @author SN
 * @date 2019/11/28
 * @description Netty服务的
 *
 * 两个线程组
 *   bossGroup: 只负责连接请求, 包含的子线程个数: 默认是cpu核数 * 2
 *   workerGroup: 负责处理客户端业务, 包含的子线程个数: 默认是cpu核数 * 2
 * NioEventLoopGroup: 包含多个NioEventLoop
 *   NioEventLoop
 *     1.每个NioEventLoop包含一个Selector(用于监听绑定在它上面的socket网络通道), 一个taskQueue
 *     2.每个NioEventLoop的Selector可以注册多个NioChannel
 *     3.每个NioChannel只会绑定到一个NioEventLoop上
 *     4.每个NioChannel都有自己的一个ChannelPipeline
 *
 */
public class NettyServer {

    public static void main(String[] args) throws Exception {

        /**
         * 创建两个线程组bossGroup和workerGroup
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //服务器启动对象
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class) //使用NioServerSocketChannel作为服务器的通道实现
                    .option(ChannelOption.SO_BACKLOG, 128) //设置线程队列得到的连接个数
                    .childOption(ChannelOption.SO_KEEPALIVE, true) //设置保持活动连接状态
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //给pipeline设置处理器
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast(new NettyServerHandler());
                        }
                    });
            //同步方式启动服务器并绑定端口, 生成一个ChannelFuture对象
            ChannelFuture cf = bootstrap.bind(10001).sync();
            //对关闭通道进行监听
            cf.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}



